import { onMounted, reactive, ref } from "vue"

/** 默认的分页参数 */
export const DEFAULT_PAGINATION_DATA = {
  total: 0,
  currentPage: 1,
  pageSizes: [10, 20, 50],
  pageSize: 10,
  layout: "total, sizes, prev, pager, next, jumper"
}

/**
 * 创建表格实例数据
 * @param {object} options - 配置选项
 * @param {object} options.api - API对象
 * @param {object} [options.pagination] - 分页配置
 * @param {object} [options.searchParams] - 搜索参数
 * @returns {object} 表格实例数据
 */
export function createTableInstance(options) {
  const { api, pagination: initPagination, searchParams = {} } = options

  // 表格数据
  const tableData = ref([])

  // 加载状态
  const loading = ref(false)

  // 分页数据
  const pagination = reactive({
    ...DEFAULT_PAGINATION_DATA,
    ...initPagination
  })

  // 选中的行
  const selectedRows = ref([])

  // 搜索参数
  const searchForm = reactive({ ...searchParams })

  // 控制查询表单的显示与隐藏
  const showSearchForm = ref(true)

  return {
    tableData,
    loading,
    pagination,
    selectedRows,
    searchForm,
    showSearchForm,
    api
  }
}

/**
 * 切换查询表单的显示状态
 * @param {object} showSearchForm - 控制显示状态的ref
 */
export function toggleSearchForm(showSearchForm) {
  showSearchForm.value = !showSearchForm.value
}

/**
 * 获取表格数据
 * @param {object} instance - 表格实例
 * @param {boolean} resetPage - 是否重置页码
 * @returns {Promise<void>} 无返回值
 */
export async function getTableData(instance, resetPage = false) {
  const { tableData, loading, pagination, searchForm, api } = instance

  if (resetPage) {
    pagination.currentPage = 1
  }

  loading.value = true
  try {
    const response = await api.getList({
      ...searchForm,
      currentPage: pagination.currentPage,
      pageSize: pagination.pageSize
    })
    tableData.value = response.data.list || []
    pagination.total = response.data.total || 0
  } catch (error) {
    console.error("获取表格数据失败:", error)
  } finally {
    loading.value = false
  }
}

/**
 * 创建数据
 * @param {object} instance - 表格实例
 * @param {object} data - 要创建的数据
 * @returns {Promise<any>} API响应
 */
export async function createData(instance, data) {
  const { loading, api } = instance

  if (!api.create) {
    throw new Error("未提供 create API")
  }

  loading.value = true
  try {
    const response = await api.create(data)
    await getTableData(instance)
    return response
  } catch (error) {
    console.error("创建数据失败:", error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 更新数据
 * @param {object} instance - 表格实例
 * @param {object} data - 要更新的数据
 * @returns {Promise<any>} API响应
 */
export async function updateData(instance, data) {
  const { loading, api } = instance

  if (!api.update) {
    throw new Error("未提供 update API")
  }

  loading.value = true
  try {
    const response = await api.update(data)
    await getTableData(instance)
    return response
  } catch (error) {
    console.error("更新数据失败:", error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 删除数据
 * @param {object} instance - 表格实例
 * @param {string | number} id - 要删除的数据ID
 * @returns {Promise<any>} API响应
 */
export async function deleteData(instance, id) {
  const { loading, api } = instance

  if (!api.delete) {
    throw new Error("未提供 delete API")
  }

  loading.value = true
  try {
    const response = await api.delete(id)
    await getTableData(instance)
    return response
  } catch (error) {
    console.error("删除数据失败:", error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 批量删除
 * @param {object} instance - 表格实例
 * @returns {Promise<void>} 无返回值
 */
export async function batchDelete(instance) {
  const { selectedRows } = instance

  if (selectedRows.value.length === 0) {
    throw new Error("请选择要删除的行")
  }

  for (const row of selectedRows.value) {
    await deleteData(instance, row.id)
  }
  selectedRows.value = []
}

/**
 * 导出数据
 * @param {object} instance - 表格实例
 * @param {object} [customParams] - 自定义参数
 * @returns {Promise<void>} 无返回值
 */
export async function exportData(instance, customParams) {
  const { loading, searchForm, api } = instance

  if (!api.export) {
    throw new Error("未提供 export API")
  }

  loading.value = true
  try {
    const blob = await api.export({
      ...searchForm,
      ...customParams
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement("a")
    link.href = url
    link.download = `导出数据_${new Date().getTime()}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    console.error("导出数据失败:", error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 下载文件
 * @param {object} instance - 表格实例
 * @param {string | number} id - 文件ID
 * @returns {Promise<void>} 无返回值
 */
export async function downloadFile(instance, id) {
  const { loading, api } = instance

  if (!api.download) {
    throw new Error("未提供 download API")
  }

  loading.value = true
  try {
    const blob = await api.download(id)
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement("a")
    link.href = url
    link.download = `文件_${id}_${new Date().getTime()}`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    console.error("下载文件失败:", error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 处理页码变化
 * @param {object} instance - 表格实例
 * @param {number} value - 新的页码
 * @returns {void} 无返回值
 */
export function handleCurrentChange(instance, value) {
  instance.pagination.currentPage = value
  getTableData(instance)
}

/**
 * 处理每页条数变化
 * @param {object} instance - 表格实例
 * @param {number} value - 新的每页条数
 * @returns {void} 无返回值
 */
export function handleSizeChange(instance, value) {
  instance.pagination.pageSize = value
  getTableData(instance, true)
}

/**
 * 处理搜索
 * @param {object} instance - 表格实例
 * @returns {void} 无返回值
 */
export function handleSearch(instance) {
  getTableData(instance, true)
}

/**
 * 处理重置
 * @param {object} instance - 表格实例
 * @returns {void} 无返回值
 */
export function handleReset(instance) {
  const { searchForm } = instance
  Object.keys(searchForm).forEach((key) => {
    searchForm[key] = ""
  })
  getTableData(instance, true)
}

/**
 * 处理选择变化
 * @param {object} instance - 表格实例
 * @param {Array} rows - 选中的行
 * @returns {void} 无返回值
 */
export function handleSelectionChange(instance, rows) {
  instance.selectedRows.value = rows
}

/**
 * 表格 Composable
 * @param {object} options - 配置选项
 * @returns {object} 表格实例和方法
 */
export function useTable(options) {
  const { immediateLoad = true } = options
  const instance = createTableInstance(options)

  // 初始加载
  onMounted(() => {
    if (immediateLoad) {
      getTableData(instance)
    }
  })

  return {
    ...instance,
    toggleSearchForm: () => toggleSearchForm(instance.showSearchForm),
    getTableData: resetPage => getTableData(instance, resetPage),
    createData: data => createData(instance, data),
    updateData: data => updateData(instance, data),
    deleteData: id => deleteData(instance, id),
    batchDelete: () => batchDelete(instance),
    exportData: customParams => exportData(instance, customParams),
    downloadFile: id => downloadFile(instance, id),
    handleCurrentChange: value => handleCurrentChange(instance, value),
    handleSizeChange: value => handleSizeChange(instance, value),
    handleSearch: () => handleSearch(instance),
    handleReset: () => handleReset(instance),
    handleSelectionChange: rows => handleSelectionChange(instance, rows)
  }
}
